
#include "FontPixelMatrix.h"

FontPixelMatrix::FontPixelMatrix(int32_t iPixelSize, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underlined, const wxString& face, wxFontEncoding encoding)
{
	m_pclsFont = new wxFont(iPixelSize, family, style, weight, underlined, face, encoding);
	m_pclsFontBitmap = new wxBitmap();
	m_pclsMDC = new wxMemoryDC();

	_create();
}

FontPixelMatrix::FontPixelMatrix(void)
{
	m_pclsFont = NULL;
	m_pclsFontBitmap = NULL;
	m_pclsMDC = NULL;
}

void FontPixelMatrix::Create(int32_t iPixelSize, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underlined, const wxString& face, wxFontEncoding encoding)
{
    if(NULL == m_pclsFont)
    {
        m_pclsFont = new wxFont(iPixelSize, family, style, weight, underlined, face, encoding);
    }
    else
    {
        m_pclsFont->Create(iPixelSize, family, style, weight, underlined, face, encoding);
    }

    if(NULL == m_pclsFontBitmap)
    {
        m_pclsFontBitmap = new wxBitmap();
    }

    if(NULL == m_pclsMDC)
    {
        m_pclsMDC = new wxMemoryDC();
    }

	_create();
}

void FontPixelMatrix::_create(void)
{
	float			fScale = 1;
	wxSize			clsMatrixSize;
	float           fPointSize, fPixelSize;

	if(true == IsOk())
	{
		// Set bitmap buffer.
		m_pclsMDC->SelectObject(*m_pclsFontBitmap);
		// Set font info.
		m_pclsMDC->SetFont(*m_pclsFont);
		// Get character height.
		clsMatrixSize = m_pclsMDC->GetTextExtent(wxString(' '));
		// Calculate font graphics scale.
		fPointSize = m_pclsFont->GetPointSize();
		fPixelSize = clsMatrixSize.GetHeight();
		fScale = fPointSize/fPixelSize;
		m_pclsFont->Scale(fScale);
		m_pclsMDC->SetFont(*m_pclsFont);
	}
}

FontPixelMatrix::~FontPixelMatrix(void)
{
	delete m_pclsFont;
	delete m_pclsFontBitmap;
	delete m_pclsMDC;
}

wxBitmap& FontPixelMatrix::ToBitmap(void)
{
	return *m_pclsFontBitmap;
}

void FontPixelMatrix::SetCharacter(wxUniChar cCode, const int32_t iGraphWidth, const int32_t iTopCut, const int32_t iBottomCut)
{
	wxSize			clsMatrixSize;
	if(0 != cCode.GetValue())
	{
		// Draw text.
		clsMatrixSize = m_pclsMDC->GetTextExtent(wxString(cCode));
		if(-1 != iGraphWidth)
		{
			clsMatrixSize.SetWidth(iGraphWidth);
		}
		m_pclsFontBitmap->Create(clsMatrixSize, 1);
		m_pclsMDC->SelectObject(*m_pclsFontBitmap);
		m_pclsMDC->SetBackground(*wxBLACK_BRUSH);
		m_pclsMDC->SetTextBackground(wxColour(0, 0, 0));
		m_pclsMDC->SetTextForeground(wxColour(255, 255, 255));
		m_pclsMDC->SetBrush(*wxBLACK_BRUSH);
		m_pclsMDC->SetPen(*wxBLACK_PEN);
		m_pclsMDC->DrawRectangle(wxPoint(0, 0), clsMatrixSize);
		m_pclsMDC->DrawText(wxString(cCode), wxPoint(0, 0));

		_cutImage(iTopCut, iBottomCut);
	}
}

void FontPixelMatrix::_cutImage(const int32_t iTopCut, const int32_t iBottomCut)
{
	wxImage				clsNewImage;
	wxBitmap			clsNewBitmap;
    wxMemoryDC			clsNewMDC;
    wxSize				clsSrcArea, clsDestArea;

	clsDestArea = m_pclsFontBitmap->GetSize();

    if((iTopCut > 0) || (iBottomCut > 0))
	{
		clsSrcArea = clsDestArea;
		// Remove the top part
		clsSrcArea.SetHeight(clsDestArea.GetHeight()-(iTopCut+iBottomCut));
		clsNewBitmap.Create(clsSrcArea, 1);
		clsNewMDC.SelectObject(clsNewBitmap);
		// Copy data.
		clsNewMDC.Blit(wxPoint(0, 0), clsSrcArea, m_pclsMDC, wxPoint(0, iTopCut));
		clsNewImage = clsNewBitmap.ConvertToImage();
		clsNewImage.Rescale(clsDestArea.GetWidth(), clsDestArea.GetHeight());
		delete m_pclsFontBitmap;
		m_pclsFontBitmap = new wxBitmap(clsNewImage);
	}
}

bool FontPixelMatrix::IsOk(void)
{
	bool	bResult = false;

	if((NULL != m_pclsFont) && (NULL != m_pclsFontBitmap) && (NULL != m_pclsMDC))
	{
		bResult = true;
	}
	return bResult;
}
